import React, { Component } from 'react'
import { findDOMNode } from 'react-dom'
import { connect } from 'react-redux'
import moment from 'moment'
import $ from 'jquery'
import _ from 'lodash'
import cs from 'classnames'
import qs from 'qs'
import Bind from 'lodash-decorators/bind'
import Throttle from 'lodash-decorators/throttle'

import {
  Spin,
  Row,
  Col
} from 'antd'
import {
  Modal as AntdModal,
  // Toast
} from 'antd-mobile'
import Layout from 'component/layout'
import Alert from 'component/alert'
import Modal from 'component/modal'
import Empty from 'component/empty'
import SuccessModal from 'component/successModal'
import HeaderLayout from 'layout/header'

import { formatMoney } from 'config/money'
import { formatTitle } from 'config/title'

import { getHouse } from 'model/house'
import { addPreSelect, lockHouse } from 'model/user'

import { loading, fail, success, hideToast } from 'utils/toast'

import style from './index.less'

const {
  Content,
  Sider
} = Layout

const { alert } = AntdModal

@connect(state => ({
  user: state.user,
  house: state.house,
  building: state.building,
}), {
  getHouse,
  addPreSelect,
  lockHouse
})
export default class App extends Component {
  isLoad = false

  constructor (props) {
    super(props)

    this.state = {
      buildingActiveId: '',
      floorActiveId: '',
      // for dom
      floorActiveIndex: null,
      houseActiveId: '',
      ...this.initActive(props),

      visibleDetail: false,
      houseDetailData: {},
      visibleSuccess: false,
      visibleTip: false,

      moving: false,
      isInit: false,

      height: document.documentElement.clientHeight
    }
  }

  componentDidMount () {
    this.props.getHouse({
      propertyId: this.props.building.propertyId,
      housePreiodId: this.props.building.housePreiodId
    })
  }

  componentDidUpdate () {
    if (!this.isLoad) {
      this.paddingHeight()
      // this.initScrollEvent()
    }

    if (this.$wrap && !this.state.isInit) {
      const $dom = findDOMNode(this.$wrap)

      const {
        offsetTop
      } = $dom

      // 初始化数据
      this.setState(prevState => ({
        height: prevState.height - offsetTop,
        isInit: true
      }))

      this.$dom = $dom
    }
  }

  componentWillReceiveProps (nextProps) {
    if (
      !this.props.house.init &&
      nextProps.house.init
    ) {
      this.setState(this.initActive(nextProps))
    }
  }

  paddingHeight = () => {
    if (!this.content) return

    const $fake = $('#fake')
    const $content = $(this.content)
    const $last = $(`.${ style['house-group'] }:last`)

    if (!$last) return

    $fake.css({
      height: $content.height() - $last.height()
    })

    this.isLoad = true
  }

  initActive = (props, index = 0) => {
    const {
      house: {
        data
      }
    } = props || this.props

    if (data.length) {
      return {
        buildingActiveId: data[index].buildNumId,
        floorActiveId: (
          data[index].floors.length ?
            data[index].floors[0].floor :
            ''
        )
      }
    }
  }

  handleActiveBuilding = (v, i, e) => {
    if (this.state.buildingActiveId === v.buildNumId) return

    this.setState({
      // buildingActiveId: v.buildNumId,
      ...this.initActive(this.props, i)
    })

    this.isLoad = false
  }

  handleActiveFloor = (v, i, e) => {
    if (this.state.moving) return

    this.setState({
      floorActiveId: v.floor,
      floorActiveIndex: i
    })

    this.setState({ moving: true }, () => {
      $(this.content).animate({
        scrollTop: document.getElementById(`house_${ v.floor }`).offsetTop - 30
      }, () => {
        setTimeout(() => {
          if (this.state.moving) {
            this.setState({ moving: false })
          }
        }, 10)
      })
    })
  }

  handleActiveHouse = (v, i, e) => {
    // 是否选房结束
    const {
      building: {
        hobSpecificEndTime
      }
    } = this.props

    const now = moment()
    const mHobSpecificEndTime = moment(hobSpecificEndTime)

    if (mHobSpecificEndTime.isValid() && now.isAfter(mHobSpecificEndTime)) {
      alert('提示', '抱歉，选房已结束！', [
        { text: '知道了' },
      ])

      return
    }

    if (this.state.houseActiveId === v.houseId) {
      this.setState({
        houseActiveId: '',
        visibleDetail: false,
        houseDetailData: {}
      })
    } else {
      this.setState({
        houseActiveId: v.houseId,
        visibleDetail: true,
        houseDetailData: {
          ...v
        }
      })
    }
  }

  addPreSelect = async (v, e) => {
    const { phone } = this.props.user
    const { housePreiodId } = this.props.building

    loading('备选中')

    const [err, res] = await this.props.addPreSelect({
      phone,
      housePreiodId,
      houseId: v.houseId,
    })

    hideToast()
    this.setState({ visibleDetail: false })

    if (err) {
      fail(err)

      return
    }

    success('备选成功')
  }

  lockHouse = async (v, e) => {
    // loading('锁房中')

    const [err, res] = await this.props.lockHouse({
      phone: this.props.user.phone,
      housePreiodId: this.props.building.housePreiodId,
      houseId: v.houseId
    })

    // hideToast()
    this.setState({ visibleDetail: false })

    if (err) {
      // fail(err)
      alert('提示', err, [
        { text: '选择其他房源' },
      ])

      return
    }
    console.log(res)

    // success('锁房成功')
    this.setState(prevState => ({
      houseDetailData: {
        ...prevState.houseDetailData,
        ...res[0]
      },

      visibleSuccess: true
    }))
  }

  @Bind()
  @Throttle(100)
  handleScroll (e) {
    if (!e || !e.target || this.state.moving) return

    const {
      scrollTop,
      clientHeight
    } = e.target

    $(`.${ style['house-group'] }`).each((i, v) => {
      if (
        scrollTop + 30 >= v.offsetTop &&
        scrollTop + 30 < v.offsetTop + v.clientHeight
      ) {

        this.setState({ floorActiveIndex: i })

        const floor = document.querySelector(`.${ style['floor'] }`)
        const item = document.getElementById(`floor_${ i + 1 }`)

        if (
          item.offsetTop + item.clientHeight > floor.clientHeight ||
          floor.scrollTop + 30 > item.offsetTop + item.clientHeight
        ) {
          floor.scrollTop = item.offsetTop
        }
      }

    })
  }

  render () {
    const {
      visibleDetail,
      visibleSuccess,

      buildingActiveId,
      floorActiveId,
      floorActiveIndex,
      houseActiveId,

      houseDetailData,
      houseDetailData: {
        excelRoomStr,

        hTotalPrice,
        hosUnitPrice,
        setInPrice,
        stationaryMoney,

        setInArea,
        hosUnitArea,
      }
    } = this.state

    const {
      history,
      house: {
        loading,
        init,
        msg,
        type,
        data
      },
      building: {
        propertyName,
        manageEndDate,
        payWay
      },
      // 备选列表和锁房列表取出来渲染在列表里
      user: {
        preSelectLimit,
        lockHouseLimit,

        lockLoading,
        preSelectHouse,
        lockHouse
      }
    } = this.props

    let renderChildren = null

    if (loading && !init || loading && !data.length) {
      renderChildren = (
        <div className = 'loading-wrap'><Spin /></div>
      )
    } else if (msg) {
      renderChildren = <Empty type = 'network' text = { <span>{ msg } <a onClick = { e => this.props.getHouse({}, true) }>重试</a></span> } />
    } else if (!data.length) {
      renderChildren = <Empty text = { <span>没有楼盘数据 <a onClick = { e => this.props.getHouse({}, true) }>重试</a></span> } />
    } else {

      const _data = _.find(data, v => v.buildNumId === buildingActiveId)

      const houseListData = _data && _data.floors ? _data.floors : []

      renderChildren = (
        <Spin spinning = { loading }>
          <BuildingTab
            data = { data }
            activeId = { buildingActiveId }
            onClick = { this.handleActiveBuilding }
          />
          <Layout withSider>
            <Content
              className = { style['content'] }
              onLoad = { el => this.content = el }
              onScroll = { e => {
                e.persist()

                this.handleScroll(e)
              } }
            >
              {
                houseListData.map((v, i) => (
                  <HouseGroup
                    id = { `house_${ v.floor }` }
                    data = { v.houses }
                    preSelectHouse = { preSelectHouse }
                    lockHouse = { lockHouse }
                    key = { i }
                    activeId = { houseActiveId }
                    onClick = { this.handleActiveHouse }

                  />
                ))
              }
              <div id = 'fake' />
            </Content>
            <Sider flex>
              <FloorTab
                activeId = { floorActiveId }
                activeIndex = { floorActiveIndex }
                data = { houseListData }
                onClick = { this.handleActiveFloor }
                onLoad = { el => this.floor = el }
              />
            </Sider>
          </Layout>
        </Spin>
      )
    }

    return (
      <HeaderLayout
        title = '选择房源'

        onBack = { () => history.replace('/home') }

        rightContent = { <div className = { style['icon-warning'] } onClick = { e => this.setState({ visibleTip: true }) } /> }

        flex
      >
        <Alert />
        { renderChildren }
        <AntdModal
          visible = { this.state.visibleDetail }
          onClose = { () => this.setState({ visibleDetail: false }) }
          animationType = 'slide-up'
          popup
        >
          <div className = { style['house'] }>
            <div className = { style['house-header'] }>
              { excelRoomStr }
            </div>
            <div className = { style['house-body'] }>
              <Row gutter = { 10 }>
                <Col span = { 12 }>
                  <div className = { style['house-info'] }>
                    <div className = { style['house-info-title'] }>房屋总价</div>
                    <div className = { style['house-info-value'] }>
                      {
                        hTotalPrice
                      }
                    </div>
                  </div>
                </Col>
                {
                  stationaryMoney ?
                    <Col span = { 12 }>
                      <div className = { style['house-info'] }>
                        <div className = { style['house-info-title'] }>定金金额</div>
                        <div className = { style['house-info-value'] }>{ stationaryMoney }</div>
                      </div>
                    </Col> :
                    null
                }
                <Col span = { 12 }>
                  <div className = { style['house-info'] }>
                    <div className = { style['house-info-title'] }>建面单价</div>
                    <div className = { style['house-info-value'] }>{ hosUnitPrice }</div>
                  </div>
                </Col>
                <Col span = { 12 }>
                  <div className = { style['house-info'] }>
                    <div className = { style['house-info-title'] }>建筑面积</div>
                    <div className = { style['house-info-value'] }>{ hosUnitArea }</div>
                  </div>
                </Col>
                <Col span = { 12 }>
                  <div className = { style['house-info'] }>
                    <div className = { style['house-info-title'] }>套内单价</div>
                    <div className = { style['house-info-value'] }>{ setInPrice }</div>
                  </div>
                </Col>
                <Col span = { 12 }>
                  <div className = { style['house-info'] }>
                    <div className = { style['house-info-title'] }>套内面积</div>
                    <div className = { style['house-info-value'] }>{ setInArea }</div>
                  </div>
                </Col>
              </Row>
            </div>
            <div className = { style['house-footer'] }>
              <div className = { style['house-footer-action'] }>
                <div className = { style['house-footer-action-cancel'] } onClick = { () => this.setState({ visibleDetail: false }) }>在考虑下</div>
                <div
                  className = { style['house-footer-action-submit'] }
                  disabled = {
                    preSelectHouse.some(v => v.houseId === houseDetailData.houseId) &&
                    type === 0 ||
                    lockHouse.some(v => v.houseId === houseDetailData.houseId)
                  }
                  onClick = {
                    e => type === 1 ? this.lockHouse(houseDetailData, e) : this.addPreSelect(houseDetailData, e)
                  }
                >
                  {
                    type === 1 ? '立即锁定' : '加入备选'
                  }
                </div>
              </div>
            </div>
          </div>
        </AntdModal>
        <Modal
          visible = { this.state.visibleTip }
          onCancel = { () => this.setState({ visibleTip: false }) }
        >
          <h2>{ type === 1 ? '选房' : '备选' }说明</h2>
          {
            type === 1 ?
              <p>1个账号只能锁定{ lockHouseLimit }套房源<br />锁定后无法更改，请谨慎选择</p> :
              <p>最多备选{ preSelectLimit }套房源，备选的房源在开盘开始前可进行变更</p>
          }
        </Modal>
        <SuccessModal
          excelRoomStr = { excelRoomStr }
          manageEndDate = { manageEndDate }
          stationaryMoney = { stationaryMoney }
          payWay = { payWay }

          visible = { visibleSuccess }
          onCancel = { () => this.setState({ visibleSuccess: false }) }
          onOk = { () => {
            if  (payWay === '3') {
              this.props.history.push(`/pay?${ qs.stringify(houseDetailData) }`)
            } else {
              this.setState({ visibleSuccess: false })
            }
          } }
        />
      </HeaderLayout>
    )
  }
}

const BuildingTab = props => {
  const {
    data,
    activeId,
    onClick,
    children
  } = props

  return (
    <div className = { style['building'] }>
      <ul>
        {
          data.map((v, i) => (
            <li
              key = { v.buildNumName }
              className = { cs({ [style['active']]: v.buildNumId === activeId }) }
              onClick = { e => onClick(v, i, e) }
            >
              { v.buildNumName }
            </li>
          ))
        }
      </ul>
    </div>
  )
}

const FloorTab = props => {
  const {
    data,
    activeIndex,
    activeId,
    onClick,
    onLoad,
    children
  } = props

  return (
    <div className = { style['floor'] } ref = { onLoad }>
      <ul>
        {
          data.map((v, i) => (
            <li
              key = { v.floor }
              id = { `floor_${ v.floor }` }
              className = {
                cs({
                  [style['active']]: (
                    !_.isNil(activeIndex) ?
                      i === activeIndex :
                      v.floor === activeId
                  )
                })
              }
              onClick = { e => onClick(v, i, e) }
            >
              { v.floor }F
            </li>
          ))
        }
      </ul>
    </div>
  )
}

const HouseGroup = props => {
  const {
    id,
    data,
    preSelectHouse,
    lockHouse,
    onClick,
    activeId,
    children
  } = props

  return (
    <div className = { style['house-group'] } id = { id }>
      <Row gutter = { 2 }>
        {
          data.map((v, i) => (
            <Col key = { i } span = { 6 }>
              <div
                className = {
                  cs(style['house-group-item'], {
                    [style[`_${ v.status }`]]: v.status,

                    [style['active']]: v.houseId === activeId,
                    [style['alternative']]: preSelectHouse.some(_v => _v.houseId === v.houseId),
                    [style['lock']]: lockHouse.some(_v => _v.houseId === v.houseId),
                  })
                }
                disabled = { v.status !== 1 }

                onClick = { e => onClick(v, i, e) }
              >
                { v.householdNo }
              </div>
            </Col>
          ))
        }
      </Row>
    </div>
  )
}
